package com.SmartClassroom.system.controller;

import com.SmartClassroom.system.annotation.AuthCheck;
import com.SmartClassroom.system.common.BaseResponse;
import com.SmartClassroom.system.common.DeleteRequest;
import com.SmartClassroom.system.common.ErrorCode;
import com.SmartClassroom.system.common.ResultUtils;
import com.SmartClassroom.system.constant.UserConstant;
import com.SmartClassroom.system.exception.BusinessException;
import com.SmartClassroom.system.exception.ThrowUtils;
import com.SmartClassroom.system.model.domain.ResourceRecord;
import com.SmartClassroom.system.model.domain.Resource;
import com.SmartClassroom.system.model.domain.User;
import com.SmartClassroom.system.model.dto.resource.ResourceAddRequest;
import com.SmartClassroom.system.model.dto.resource.ResourceQueryRequest;
import com.SmartClassroom.system.model.dto.resource.ResourceStatusUpdateRequest;
import com.SmartClassroom.system.model.dto.resource.ResourceUpdateRequest;
import com.SmartClassroom.system.model.dto.resource.ResourceBorrowRequest;
import com.SmartClassroom.system.model.vo.ResourceVO;
import com.SmartClassroom.system.service.ResourceRecordService;
import com.SmartClassroom.system.service.ResourceService;
import com.SmartClassroom.system.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 教室资源管理接口
 *
 * @author baijiayu
 */
@RestController
@RequestMapping("/resource")
@Slf4j
@Api(tags = { "教室资源管理接口" })
public class ResourceController {

    @javax.annotation.Resource
    private UserService userService;

    @javax.annotation.Resource
    private ResourceRecordService resourceRecordService;

    @javax.annotation.Resource
    private ResourceService resourceService;

    // region 增删改查

    /**
     * 创建资源借出记录
     *
     * @param resourceBorrowRequest 资源借出请求
     * @param request               HTTP请求
     * @return BaseResponse<Integer> 借出记录ID
     */
    @PostMapping("/out")
    @ApiOperation(value = "创建资源借出记录")
    public BaseResponse<Integer> borrowResource(@RequestBody ResourceBorrowRequest resourceBorrowRequest,
            HttpServletRequest request) {
        if (resourceBorrowRequest == null || resourceBorrowRequest.getResourceName() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }

        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);
        String userName = loginUser.getUserName();

        // 检查该资源是否已被借出
        QueryWrapper<ResourceRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("resourceName", resourceBorrowRequest.getResourceName())
                .eq("status", "out")
                .eq("isDelete", 0);
        ResourceRecord existingRecord = resourceRecordService.getOne(queryWrapper);
        if (existingRecord != null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "该资源已被借出");
        }

        // 创建借出记录
        ResourceRecord resourceRecord = new ResourceRecord();
        resourceRecord.setResourceName(resourceBorrowRequest.getResourceName());
        resourceRecord.setStatus("out");
        resourceRecord.setUserName(userName);

        // 保存记录
        boolean result = resourceRecordService.save(resourceRecord);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "借出失败");

        return ResultUtils.success(resourceRecord.getResourceId());
    }

    /**
     * 删除资源借出记录
     *
     * @param deleteRequest
     * @return
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @ApiOperation(value = "删除资源借出记录")
    public BaseResponse<Boolean> deleteUser(@RequestBody DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = resourceRecordService.removeById(deleteRequest.getId());
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "删除失败");
        return ResultUtils.success(result);
    }

    /**
     * 更新资源借出记录
     *
     * @param resourceUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @ApiOperation(value = "更新资源借出记录")
    public BaseResponse<Boolean> updateResource(@RequestBody ResourceUpdateRequest resourceUpdateRequest) {
        if (resourceUpdateRequest == null || resourceUpdateRequest.getResourceId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        QueryWrapper<ResourceRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("resourceId", resourceUpdateRequest.getResourceId());
        ResourceRecord record = resourceRecordService.getOne(queryWrapper);
        if (record == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        BeanUtils.copyProperties(resourceUpdateRequest, record);
        boolean result = resourceRecordService.updateById(record);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "更新失败");
        return ResultUtils.success(result);
    }

    /**
     * 资源归还请求
     *
     * @param resourceStatusUpdateRequest 资源归还请求，只需要提供记录ID
     * @param request                     HTTP请求
     * @return BaseResponse<Boolean> 归还是否成功
     */
    @PostMapping("/in")
    @ApiOperation(value = "资源归还请求")
    public BaseResponse<Boolean> returnResource(@RequestBody ResourceStatusUpdateRequest resourceStatusUpdateRequest,
            HttpServletRequest request) {
        // 参数校验
        if (resourceStatusUpdateRequest == null || resourceStatusUpdateRequest.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "记录ID不能为空");
        }

        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);
        String userName = loginUser.getUserName();

        // 查询资源记录
        ResourceRecord record = resourceRecordService.getById(resourceStatusUpdateRequest.getId());
        ThrowUtils.throwIf(record == null, ErrorCode.NOT_FOUND_ERROR, "资源记录不存在");

        // 验证是否是自己借出的资源
        if (!userName.equals(record.getUserName())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "只能归还自己借出的资源");
        }

        // 验证资源是否处于借出状态
        if (!"out".equals(record.getStatus())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "该资源未被借出，无需归还");
        }

        // 更新状态为归还
        record.setStatus("in");
        boolean result = resourceRecordService.updateById(record);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "资源归还失败");

        return ResultUtils.success(true);
    }

    /**
     * 分页获取资源借出记录列表
     *
     * @param resourceQueryRequest
     * @return
     */
    @PostMapping("/list/page")
    @ApiOperation(value = "分页获取资源借出记录列表")
    public BaseResponse<Page<ResourceRecord>> listResourceByPage(
            @RequestBody ResourceQueryRequest resourceQueryRequest) {
        long current = resourceQueryRequest.getCurrent() == 0 ? 1 : resourceQueryRequest.getCurrent();
        long size = resourceQueryRequest.getPageSize() == 0 ? 10 : resourceQueryRequest.getPageSize();
        Page<ResourceRecord> pageParam = new Page<>(current, size);
        Page<ResourceRecord> resourceRecordPage = resourceRecordService.getQueryWrapper(pageParam,
                resourceQueryRequest);
        return ResultUtils.success(resourceRecordPage);
    }

    /**
     * 获取用户自己的资源借出记录列表
     *
     * @param resourceQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/list/page/my")
    @ApiOperation(value = "获取用户自己的资源借出记录列表")
    public BaseResponse<Page<ResourceRecord>> listUserVOByPage(
            @RequestBody ResourceQueryRequest resourceQueryRequest, HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        String userName = loginUser.getUserName();
        long current = resourceQueryRequest.getCurrent() == 0 ? 1 : resourceQueryRequest.getCurrent();
        long size = resourceQueryRequest.getPageSize() == 0 ? 10 : resourceQueryRequest.getPageSize();
        Page<ResourceRecord> pageParam = new Page<>(current, size);
        Page<ResourceRecord> resourceRecordPage = resourceRecordService.getQueryWrapperByName(pageParam,
                resourceQueryRequest, userName);
        return ResultUtils.success(resourceRecordPage);
    }

    /**
     * 管理员添加新资源
     *
     * @param resourceAddRequest 资源添加请求
     * @return BaseResponse<Long> 新增资源的ID
     */
    @PostMapping("/add")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @ApiOperation(value = "管理员添加新资源")
    public BaseResponse<Long> addNewResource(@RequestBody ResourceAddRequest resourceAddRequest,
            HttpServletRequest request) {
        // 参数校验
        if (resourceAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        String title = resourceAddRequest.getTitle();
        String type = resourceAddRequest.getType();
        if (title == null || type == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "资源名称或类型不能为空");
        }

        // 检查资源名称是否已存在
        QueryWrapper<Resource> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("title", title)
                .eq("is_delete", 0);
        Resource existingResource = resourceService.getOne(queryWrapper);
        if (existingResource != null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "该资源名称已存在");
        }

        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);

        // 创建新的资源对象
        Resource resource = new Resource();
        resource.setTitle(title);
        resource.setDescription(resourceAddRequest.getDescription());
        resource.setType(type);

        // 调用服务添加资源
        long resourceId = resourceService.addResource(resource, loginUser.getId());

        return ResultUtils.success(resourceId);
    }

    /**
     * 管理员删除资源
     *
     * @param deleteRequest 删除请求
     * @return BaseResponse<Boolean>
     */
    @PostMapping("/deleteResource")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @ApiOperation(value = "管理员删除资源")
    public BaseResponse<Boolean> deleteResource(@RequestBody DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        // 判断资源是否存在
        Resource resource = resourceService.getById(deleteRequest.getId());
        ThrowUtils.throwIf(resource == null, ErrorCode.NOT_FOUND_ERROR, "资源不存在");

        // 执行删除
        boolean result = resourceService.removeById(deleteRequest.getId());
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "删除失败");

        return ResultUtils.success(true);
    }

    /**
     * 查看全部资源
     *
     * @return 资源列表
     */
    @GetMapping("/list/all")
    @ApiOperation(value = "查看全部资源")
    public BaseResponse<Page<ResourceVO>> listAllResources() {
        // 创建查询条件，只查询未删除的资源
        QueryWrapper<Resource> queryWrapper = new QueryWrapper<>();
        // 按创建时间降序排序
        queryWrapper.orderByDesc("create_time");
        // 查询所有资源
        List<Resource> resourceList = resourceService.list(queryWrapper);

        // 转换为 VO 对象
        List<ResourceVO> resourceVOList = resourceList.stream().map(resource -> {
            ResourceVO resourceVO = new ResourceVO();
            BeanUtils.copyProperties(resource, resourceVO);
            // 获取创建者用户名
            User creator = userService.getById(resource.getCreatorId());
            if (creator != null) {
                resourceVO.setCreatorName(creator.getUserName());
            }
            return resourceVO;
        }).collect(Collectors.toList());
        Page<ResourceVO> resourceVOPage = new Page<>();
        resourceVOPage.setRecords(resourceVOList);
        resourceVOPage.setTotal(resourceList.size());
        resourceVOPage.setSize(resourceList.size());

        return ResultUtils.success(resourceVOPage);
    }

    // endregion
}
